/********************************************************************************
 * @file    bsp_pwm.c
 * @author  jianqiang.xue
 * @version V1.0.0
 * @date    2021-04-18
 * @brief   NULL
 ********************************************************************************/

/* Includes ------------------------------------------------------------------*/
#include "RTE_Components.h"
#include CMSIS_device_header

#include "bsp_gpio.h"
#include "bsp_pwm.h"
#include "bsp_tim.h"

/* Private Includes ----------------------------------------------------------*/
#include "ls_gpio.h"
#include "ls_syscfg.h"
#include "log.h"
/* Private Variables ---------------------------------------------------------*/
static bool g_pwm_init = false;
#if LS_TIM1_EN
extern TIM_HandleTypeDef *g_tim1_handle;
extern TIM_OC_InitTypeDef *g_tim1_oc_handle;
#endif

#if LS_TIM2_EN
extern TIM_HandleTypeDef *g_tim2_handle;
extern TIM_OC_InitTypeDef *g_tim2_oc_handle;
#endif
/* Public function prototypes -----------------------------------------------*/
/**
 * @brief  设置PWM占空比
 * @param  pwmx: PWM组号
 * @param  val: 0-PERIOD PWM值   ls_syscfg.h -- LS_TIMx_PERIOD
 * @retval 0 -- 执行成功  1 -- 执行失败
 */
uint8_t bsp_pwm_set_pulse(bsp_pwm_t pwmx, uint16_t val) {
    switch (pwmx) {
#if LS_TIM1_EN
#if LS_PWM0_EN
        case BSP_PWM_0:
            HAL_TIM_PWM_Stop(g_tim1_handle, TIM_CHANNEL_1);
            if (val == -1 || val > g_tim1_handle->Init.Period) val = g_tim1_handle->Init.Period;
            g_tim1_oc_handle->Pulse = val;
            HAL_TIM_PWM_ConfigChannel(g_tim1_handle, g_tim1_oc_handle, TIM_CHANNEL_1);
            HAL_TIM_PWM_Start(g_tim1_handle, TIM_CHANNEL_1);
            break;
#endif
#if LS_PWM1_EN
        case BSP_PWM_1:
            HAL_TIM_PWM_Stop(g_tim1_handle, TIM_CHANNEL_2);
            if (val == -1 || val > g_tim1_handle->Init.Period) val = g_tim1_handle->Init.Period;
            g_tim1_oc_handle->Pulse = val;
            //LOGD("%d,%d",g_tim1_oc_handle->Pulse,val);
            HAL_TIM_PWM_ConfigChannel(g_tim1_handle, g_tim1_oc_handle, TIM_CHANNEL_2);
            HAL_TIM_PWM_Start(g_tim1_handle, TIM_CHANNEL_2);
            break;
#endif
#if LS_PWM2_EN
        case BSP_PWM_2:
            HAL_TIM_PWM_Stop(g_tim1_handle, TIM_CHANNEL_3);
            if (val == -1 || val > g_tim1_handle->Init.Period) val = g_tim1_handle->Init.Period;
            g_tim1_oc_handle->Pulse = val;
            HAL_TIM_PWM_ConfigChannel(g_tim1_handle, g_tim1_oc_handle, TIM_CHANNEL_3);
            HAL_TIM_PWM_Start(g_tim1_handle, TIM_CHANNEL_3);
            break;
#endif
#if LS_PWM3_EN
        case BSP_PWM_3:
            HAL_TIM_PWM_Stop(g_tim1_handle, TIM_CHANNEL_4);
            if (val == -1 || val > g_tim1_handle->Init.Period) val = g_tim1_handle->Init.Period;
            g_tim1_oc_handle->Pulse = val;
            HAL_TIM_PWM_ConfigChannel(g_tim1_handle, g_tim1_oc_handle, TIM_CHANNEL_4);
            HAL_TIM_PWM_Start(g_tim1_handle, TIM_CHANNEL_4);
            break;
#endif
#endif
#if LS_TIM2_EN
#if LS_PWM4_EN
        case BSP_PWM_4:
            HAL_TIM_PWM_Stop(g_tim2_handle, TIM_CHANNEL_1);
            if (val == -1 || val > g_tim2_handle->Init.Period) val = g_tim2_handle->Init.Period;
            g_tim2_oc_handle->Pulse = val;
            HAL_TIM_PWM_ConfigChannel(g_tim2_handle, g_tim2_oc_handle, TIM_CHANNEL_1);
            HAL_TIM_PWM_Start(g_tim2_handle, TIM_CHANNEL_1);
            break;
#endif
#if LS_PWM5_EN
        case BSP_PWM_5:
            HAL_TIM_PWM_Stop(g_tim2_handle, TIM_CHANNEL_2);
            if (val == -1 || val > g_tim2_handle->Init.Period) val = g_tim2_handle->Init.Period;
            g_tim2_oc_handle->Pulse = val;
            HAL_TIM_PWM_ConfigChannel(g_tim2_handle, g_tim2_oc_handle, TIM_CHANNEL_2);
            HAL_TIM_PWM_Start(g_tim2_handle, TIM_CHANNEL_2);
            break;
#endif
#if LS_PWM6_EN
        case BSP_PWM_6:
            HAL_TIM_PWM_Stop(g_tim2_handle, TIM_CHANNEL_3);
            if (val == -1 || val > g_tim2_handle->Init.Period) val = g_tim2_handle->Init.Period;
            g_tim2_oc_handle->Pulse = val;
            HAL_TIM_PWM_ConfigChannel(g_tim2_handle, g_tim2_oc_handle, TIM_CHANNEL_3);
            HAL_TIM_PWM_Start(g_tim2_handle, TIM_CHANNEL_3);
            break;
#endif
#if LS_PWM7_EN
        case BSP_PWM_7:
            HAL_TIM_PWM_Stop(g_tim2_handle, TIM_CHANNEL_4);
            if (val == -1 || val > g_tim2_handle->Init.Period) val = g_tim2_handle->Init.Period;
            g_tim2_oc_handle->Pulse = val;
            HAL_TIM_PWM_ConfigChannel(g_tim2_handle, g_tim2_oc_handle, TIM_CHANNEL_4);
            HAL_TIM_PWM_Start(g_tim2_handle, TIM_CHANNEL_4);
            break;
#endif
#endif
        default:
            return 1;
    }
    return 0;
}

uint16_t bsp_pwm_get_pulse(bsp_pwm_t pwmx) {
    switch (pwmx) {
#if LS_TIM1_EN
#if LS_PWM0_EN
        case BSP_PWM_0:
            return g_tim1_handle->Instance->CCR1;
#endif
#if LS_PWM1_EN
        case BSP_PWM_1:
            return g_tim1_handle->Instance->CCR2;
#endif
#if LS_PWM2_EN
        case BSP_PWM_2:
            return g_tim1_handle->Instance->CCR3;
#endif
#if LS_PWM3_EN
        case BSP_PWM_3:
            return g_tim1_handle->Instance->CCR4;
#endif
#endif
#if LS_TIM2_EN
#if LS_PWM4_EN
        case BSP_PWM_4:
            return g_tim2_handle->Instance->CCR1;
#endif
#if LS_PWM5_EN
        case BSP_PWM_5:
            return g_tim2_handle->Instance->CCR2;
#endif
#if LS_PWM6_EN
        case BSP_PWM_6:
            return g_tim2_handle->Instance->CCR3;
#endif
#if LS_PWM7_EN
        case BSP_PWM_7:
            return g_tim2_handle->Instance->CCR4;
#endif
#endif
    }
    return 0;
}

/**
 * @brief 百分比转装载值
 * @param  pwmx: PWM组号
 * @param  pp: 百分比
 * @retval 装载值
 */
uint16_t bsp_pwm_pp_to_pulse(bsp_pwm_t pwmx, uint8_t pp) {
    switch (pwmx) {
#if LS_TIM1_EN
#if LS_PWM0_EN
        case BSP_PWM_0:
            return (uint16_t)(g_tim1_handle->Init.Period * (pp / 100.0));
#endif
#if LS_PWM1_EN
        case BSP_PWM_1:
            return (uint16_t)(g_tim1_handle->Init.Period * (pp / 100.0));
#endif
#if LS_PWM2_EN
        case BSP_PWM_2:
            return (uint16_t)(g_tim1_handle->Init.Period * (pp / 100.0));
#endif
#if LS_PWM3_EN
        case BSP_PWM_3:
            return (uint16_t)(g_tim1_handle->Init.Period * (pp / 100.0));
#endif
#endif
#if LS_TIM2_EN
#if LS_PWM4_EN
        case BSP_PWM_4:
            return (uint16_t)(g_tim2_handle->Init.Period * (pp / 100.0));
#endif
#if LS_PWM5_EN
        case BSP_PWM_5:
            return (uint16_t)(g_tim2_handle->Init.Period * (pp / 100.0));
#endif
#if LS_PWM6_EN
        case BSP_PWM_6:
            return (uint16_t)(g_tim2_handle->Init.Period * (pp / 100.0));
#endif
#if LS_PWM7_EN
        case BSP_PWM_7:
            return (uint16_t)(g_tim2_handle->Init.Period * (pp / 100.0));
#endif
#endif
    }
    return 0;
}
